﻿#region License Information
/* Adapted by Stefan S. in Fall 2012
 * 
 * HeuristicLab
 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
 *
 * Liscenced under GNU GPL v3
 */
#endregion

using System;

namespace Simulated_Annealing
{
    /// <summary>
    /// Describes instances of the Vehicle Routing Problem (VRP).
    /// </summary>
    public class CVRPData
    {
        private TSPLIBParser myParser;

        public CVRPData(TSPLIBParser myParser)
        {
            this.myParser = myParser;
            Capacity = myParser.Capacity;
            Coordinates = myParser.Vertices;
            Demands = myParser.Demands;
            Dimension = myParser.Dimension;
            Name = myParser.Name;

            Distances = new double[Dimension, Dimension];
            for (int i = 0; i < Dimension; i++)
            {
                for (int j = i + 1; j < Dimension; j++)
                {
                    Distances[i, j] = Math.Sqrt((Coordinates[i, 1] - Coordinates[j, 1]) * (Coordinates[i, 1] - Coordinates[j, 1]) + (Coordinates[i, 0] - Coordinates[j, 0]) * (Coordinates[i, 0] - Coordinates[j, 0]));
                    Distances[j, i] = Distances[i, j];
                }
            }

            Validate();
        }

        /// <summary>
        /// The name of the instance
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// The number of customers and the depot
        /// </summary>
        public int Dimension { get; private set; }

        /// <remarks>
        /// Distances computed from coordinates
        /// </remarks>
        public double[,] Distances { get; private set; }

        /// <summary>
        /// Coordinates read from file
        /// </remarks>
        private double[,] Coordinates { get; set; }

        /// <summary>
        /// The demand vector that specifies how many goods need to be delivered.
        /// The vector has to include the depot, but with a demand of 0.
        /// </summary>
        public double[] Demands { get; private set; }

        /// <summary>
        /// The capacity of the vehicles, which is the same for all (homogeneous fleet).
        /// </summary>
        public double Capacity { get; private set; }
        
        /// <summary>
        /// Makes sure data makes sense
        /// </summary>
        private void Validate()
        {
            if (Dimension < 1)
                throw new Exception("Dimension < 1");

            if (Distances.Length != Dimension * Dimension)
                throw new Exception("Distances.Length != Dimension * Dimension");

            if (Demands.Length != Dimension)
                throw new Exception("Demands.Length != Dimension");

            for (int i = 0; i < Dimension; i++)
            {
                if (Demands[i] < 0)
                    throw new Exception("Demands[" + i + "] < 0");

                if (Demands[i] == 0 && i > 0)
                    Console.WriteLine("WARNING: Demands[" + i + "] == 0");

                if (Demands[i] > Capacity)
                    throw new Exception("Demands[" + i + "] > Capacity");

                for (int j = i + 1; j < Dimension; j++)
                {
                    if (Distances[i, j] == 0)
                        Console.WriteLine("WARNING: Distances[" + i + "," + j + "] == 0");
                }
            }

            if (Capacity <= 0)
                throw new Exception("Capacity <= 0");

            Console.WriteLine("Data Validated");
        }
    }
}
